home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / machack / Hacks97 / VerticalHold.sit / Vertical Hold / source code / Bzzt.cpp next >
C/C++ Source or Header  |  1997-06-27  |  8KB  |  370 lines

  1. #include <LowMem.h>
  2. #include <A4Stuff.h>
  3. #include <QuickDraw.h>
  4. #include <Memory.h>
  5. #include <Resources.h>
  6. #include <Fonts.h>
  7. #include <Dialogs.h>
  8. #include <QDOffscreen.h>
  9. #include <string.h>
  10. #include <stdio.h>
  11. #include <Timer.h>
  12.  
  13. #define        SIMPLE        0
  14.  
  15. #define    PreserveFlags(x, y)        ((x & 0xC000) | (y & 0x3FFF))
  16.  
  17. #define    crsrBase    0x898
  18.  
  19. enum {
  20.     uppA5Info = kCStackBased | RESULT_SIZE(SIZE_CODE(sizeof(long)))
  21.         | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long)))
  22. };
  23.  
  24. enum {
  25.     uppMyProcInfo = kPascalStackBased
  26. };
  27.  
  28. unsigned long    __procinfo = uppMyProcInfo;
  29.  
  30. typedef struct {
  31.     TMTask            task;
  32.     Ptr                mainBaseAddr;
  33.     Size            worldBytes;
  34.     Ptr                worldBuffer;
  35.     short            rowBytes;
  36.     short            phase;
  37.     Rect            size;
  38.     short            offset;
  39. } MyTaskRec;
  40.  
  41. #define            kUpdateSpeed        90
  42.  
  43. typedef struct {
  44.     short            numPorts;
  45.     GrafPtr            ports [1];
  46. } **PortListHdl;
  47.  
  48. int currentPlug = 0;
  49.  
  50. static bool Bypass ()
  51. {
  52.     char*        t = (char*)0x17b;
  53.     char*        t2 = (char*) 0x183;
  54.     
  55.     if(*t2 & 4)
  56.         currentPlug = 0;
  57.     if(*t2 & 1)
  58.         currentPlug = 1;
  59.         
  60.     t2 = (char *) 0x180;
  61.     if(*t2 & 8)
  62.         currentPlug = 2;
  63.     if(*t2 & 1)
  64.         currentPlug = 4;
  65.     if(*t2 & 2)
  66.         currentPlug = 5;
  67.     if(*t2 & 4)
  68.         currentPlug = 6;
  69.     if(*t2 & 16)
  70.         currentPlug = 7;
  71.     if(*t2 & 32)
  72.         currentPlug = 8;
  73.     
  74.     t2 = (char *) 0x182;
  75.     if(*t2 & 0x40)
  76.         currentPlug = 3;
  77.     
  78.     
  79.     if (*t & 2)
  80.         return true;
  81.     else
  82.         return false;
  83. }
  84.  
  85. void doWavePlug(MyTaskRec* myTask);
  86. void doScrollerPlug(MyTaskRec* myTask);
  87. void doFallingDoorPlug(MyTaskRec* myTask);
  88. void doKaliedPlug(MyTaskRec* myTask);
  89. void doSlidePlug(MyTaskRec* myTask);
  90. void doMungePlug(MyTaskRec* myTask);
  91. void doPixelatorPlug(MyTaskRec* myTask);
  92. void doInvertPlug(MyTaskRec* myTask);
  93. void doSnowPlug(MyTaskRec* myTask);
  94.  
  95.  
  96.  
  97. static
  98. void ChangeAllPorts (Ptr oldBaseAddr, Ptr newBaseAddr)
  99. {        
  100.     PortListHdl        ports = *((PortListHdl*) 0x0000d66);
  101.  
  102.     for (int i = 0; i < (**ports).numPorts; ++i) {
  103.     
  104.         if ((**ports).ports [i] -> portBits.rowBytes & 0xC000) {
  105.                 
  106.             CGrafPtr        port = (CGrafPtr) ((**ports).ports [i]);
  107.             
  108.             if (GetPixBaseAddr (port -> portPixMap) == oldBaseAddr)
  109.                 (**(port -> portPixMap)).baseAddr = newBaseAddr;
  110.     
  111.         } else {
  112.         
  113.             GrafPtr            port = ((**ports).ports [i]);
  114.  
  115.             if (port -> portBits.baseAddr == oldBaseAddr)
  116.                 port -> portBits.baseAddr = newBaseAddr;
  117.         
  118.         }
  119.     }
  120. }
  121.  
  122. static
  123. pascal void SimpleBlit (MyTaskRec* myTask)
  124. {    
  125.     short            height = myTask -> size.bottom - myTask -> size.top;
  126.     short            phase = myTask -> phase;
  127.     short            rowBytes = myTask -> rowBytes;
  128.     Ptr                worldBuffer = myTask -> worldBuffer;
  129.     Ptr                screenBuffer = myTask -> mainBaseAddr;
  130.  
  131.     BlockMoveDataUncached (worldBuffer, screenBuffer, height * rowBytes);
  132. }
  133.  
  134. static void FancyBlit (MyTaskRec* myTask)
  135. {    
  136.     short            height = myTask -> size.bottom - myTask -> size.top;
  137.     short            phase = myTask -> phase;
  138.     short            rowBytes = myTask -> rowBytes;
  139.     Ptr                worldBuffer = myTask -> worldBuffer;
  140.     Ptr                screenBuffer = myTask -> mainBaseAddr;
  141.  
  142.     BlockMoveDataUncached (worldBuffer + phase * rowBytes, screenBuffer, (height - phase) * rowBytes);
  143.     BlockMoveDataUncached (worldBuffer, screenBuffer + (height - phase) * rowBytes, phase * rowBytes);
  144.  
  145.     phase += myTask -> offset;
  146.     if (phase >= height)
  147.         phase = 0;
  148.     else if (phase < 0)
  149.         phase = height;
  150.         
  151.     myTask -> phase = phase;
  152. }
  153.  
  154. void doWavePlug(MyTaskRec* myTask);
  155. void doScrollerPlug(MyTaskRec* myTask);
  156. void doFallingDoorPlug(MyTaskRec* myTask);
  157. void doKaliedPlug(MyTaskRec* myTask);
  158.  
  159. pascal void MyCTimerProc (MyTaskRec* myTask);
  160.  
  161. /*
  162. static asm void MyTimerProc ()
  163. {
  164.     move.l    a1, -(sp)
  165.     jsr MyCTimerProc
  166.     rts
  167. }
  168. */
  169.  
  170. typedef struct {
  171.     QDGlobals            qd;                                    // Storage for the QuickDraw globals
  172.     long                qdGlobalsPtr;                            // A5 points to this place; it will contain a pointer to qd
  173. } QDStorage;
  174.  
  175. MyTaskRec            myTask;
  176.  
  177. static long MySetA5 (void* value)
  178. {
  179.     short                hex [7] = {
  180.             0x4e56,
  181.             0x0000,
  182.             0x202e,
  183.             0x0008,
  184.             0xc18d,
  185.             0x4e5e,
  186.             0x4e75
  187.         };
  188.  
  189.  
  190.     MakeDataExecutable (&hex, 14);
  191.             
  192.     UniversalProcPtr    upp = NewRoutineDescriptor ((ProcPtr) &hex, uppA5Info, kM68kISA);
  193.     if (!upp)
  194.         DebugStr ("\pDONT EVEN THINK ABOUT IT!");
  195.  
  196.     long        oldA5 = CallUniversalProc (upp, uppA5Info, value);
  197.  
  198.     return oldA5;
  199. }
  200.  
  201. pascal void MyCTimerProc (MyTaskRec* myTask)
  202. {    
  203.     EnterCodeResource ();
  204.     if (Bypass ())
  205.     {
  206.         switch(currentPlug)
  207.         {
  208.             case 0:
  209.                 doMungePlug(myTask);
  210.                 break;
  211.             case 1:
  212.                 FancyBlit (myTask);
  213.                 break;
  214.             case 2:
  215.                 doInvertPlug(myTask);
  216.                 break;
  217.             case 3:
  218.                 doScrollerPlug(myTask);
  219.                 break;
  220.             case 4:
  221.                 doSlidePlug (myTask);
  222.                 break;
  223.             case 5:
  224.                 doFallingDoorPlug(myTask);
  225.                 break;
  226.             case 6:
  227.                 doPixelatorPlug(myTask);
  228.                 break;
  229.             case 7:
  230.                 doKaliedPlug(myTask);
  231.                 break;
  232.             case 8:
  233.                 doWavePlug(myTask);
  234.                 break;
  235.         }
  236.     }
  237.     else
  238.         SimpleBlit (myTask);
  239.         
  240.     ExitCodeResource ();
  241.     PrimeTime ((QElemPtr) myTask, kUpdateSpeed);
  242. }
  243.  
  244. static void Override ()
  245. {
  246.     long                oldA5;                                // Original value of register A5
  247.     QDStorage            qds;                                    // Fake QD globals
  248.  
  249.     oldA5 = MySetA5(&qds.qdGlobalsPtr);                        // Tell A5 to point to the end of the fake QD Globals
  250.     InitGraf(&qds.qd.thePort);                                // Initialize the fake QD Globals
  251.         
  252.     GDHandle            mainDevice = GetMainDevice ();    
  253.     PixMapHandle        mainPixMap = (**mainDevice).gdPMap;
  254.     Rect                mainBounds = (**mainDevice).gdRect;
  255.     short                mainRowBytes = (**(**mainDevice).gdPMap).rowBytes;
  256.     
  257.     myTask.mainBaseAddr = (**(**mainDevice).gdPMap).baseAddr;
  258.     myTask.phase = 0;
  259.     
  260.     GWorldPtr            world = nil;
  261.     
  262.     Rect                tempBounds = mainBounds;
  263.     tempBounds.bottom = tempBounds.top + 1;
  264.     
  265.     if (NewGWorld (&world, (**mainPixMap).pixelSize, &tempBounds, nil, nil, 0))
  266.         goto Exit;        
  267.     
  268.     GDHandle            device = GetGWorldDevice (world);
  269.     PixMapHandle        worldPixMap = GetGWorldPixMap (world);
  270.  
  271.     // GWorld is really short, make a new buffer for it
  272.     Ptr                    oldWorldBuffer = (**worldPixMap).baseAddr;
  273.     short                oldWorldRowBytes = (**worldPixMap).rowBytes;
  274.     
  275.     long                bytesNeeded = (mainBounds.bottom - mainBounds.top) * (mainRowBytes & 0x3FFF);
  276.     
  277.     Ptr                    newWorldBuffer = NewPtrSys (bytesNeeded);
  278.     if (!newWorldBuffer)
  279.         goto Exit;
  280.  
  281.     LockPixels (worldPixMap);
  282.  
  283.     (**worldPixMap).baseAddr = newWorldBuffer;
  284.     (**worldPixMap).rowBytes = mainRowBytes;
  285.     (**worldPixMap).bounds = mainBounds;
  286.  
  287.     LockPixels (mainPixMap);
  288.  
  289.     short                worldRowBytes = (**worldPixMap).rowBytes;
  290.     myTask.worldBytes = (mainBounds.bottom - mainBounds.top) * (worldRowBytes & 0x3FFF);        
  291.     myTask.worldBuffer = GetPixBaseAddr (worldPixMap);
  292.     myTask.rowBytes = worldRowBytes & 0x3FFF;
  293.     myTask.size = mainBounds;
  294.     
  295.     *((Ptr*)crsrBase) = myTask.worldBuffer;
  296.      
  297.     (**(**mainDevice).gdPMap).baseAddr = myTask.worldBuffer;
  298.     GDeviceChanged (mainDevice);
  299.         
  300.     GrafPtr                wMgrPort;
  301.     GetWMgrPort (&wMgrPort);
  302.  
  303.     short                wMgrRowBytes = wMgrPort -> portBits.rowBytes;
  304.  
  305.     wMgrPort -> portBits.baseAddr = myTask.worldBuffer;
  306.  
  307.     CGrafPtr            cwMgrPort;
  308.     GetCWMgrPort (&cwMgrPort);
  309.  
  310.     short                cwMgrRowBytes = (**(cwMgrPort -> portPixMap)).rowBytes;
  311.  
  312.     (**cwMgrPort -> portPixMap).baseAddr = myTask.worldBuffer;
  313.     
  314.     LMSetScrnBase (myTask.worldBuffer);
  315.     
  316.     ChangeAllPorts (myTask.mainBaseAddr, myTask.worldBuffer);
  317.     
  318.     BlockMoveDataUncached (myTask.mainBaseAddr, myTask.worldBuffer, myTask.worldBytes);
  319.  
  320.     myTask.task.tmAddr = (TimerUPP) NewTimerProc (MyCTimerProc);
  321.     
  322.     myTask.task.tmCount = 0;
  323.     myTask.task.tmWakeUp = 0;
  324.     myTask.task.tmReserved = 0;
  325.     myTask.offset = -5;
  326.     
  327.     MySetA5((void*)oldA5);
  328.  
  329.     InsXTime ((QElemPtr) &myTask);
  330.     PrimeTime ((QElemPtr) &myTask, 300);
  331.     
  332.     return;
  333.     
  334. Exit:
  335.     DebugStr ("\pError");
  336. }
  337.  
  338. void initWavePlug();
  339.  
  340. extern "C" {
  341.     pascal
  342.     void main ();
  343. }
  344.  
  345. pascal
  346. void main ()
  347. {
  348.     EnterCodeResource ();
  349.  
  350.     THz                    oldZone = GetZone ();
  351.     SetZone (SystemZone ());
  352.         
  353.     Handle                me = Get1IndResource ('INIT', 1);
  354.     HLock (me);
  355.         
  356.     if (!me)
  357.         goto Exit;
  358.     
  359.     initWavePlug();
  360.     Override ();
  361.  
  362.     DetachResource (me);
  363.  
  364.  
  365. Exit:
  366.     SetZone (oldZone);
  367.     ExitCodeResource ();
  368. }
  369.  
  370.